package com.apexedu.lbwsclient;

import com.apexedu.lbwsclient.business.*;
import com.apexedu.lbwsclient.document.*;
import com.apexedu.util.StringUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.IOException;
import java.util.List;

/**
 * LiveBOS Server的 WebService 接口 及配置信息
 * Created by 杨建亮 on 2015/7/3.
 */
public class LiveBosWebServiceUtils {

    public static final Log LOG = LogFactory.getLog(LiveBosWebServiceUtils.class);

//    public static final String LBE_SERVER_URL = SysPropertiesUtil.get("LBE_SERVER_URL");//webservice应用服务器地址
    public static final String LBE_SERVER_URL = "http://202.194.7.34:8090";//webservice应用服务器地址
    public static final String LBEBusiness_URL = LBE_SERVER_URL + "/service/LBEBusiness?wsdl";//基础接口地址
    public static final String LBEDocument_URL = LBE_SERVER_URL + "/service/LBDocument?wsdl";//文档接口地址
//    public static final String LBE_LOGIN_USERID = SysPropertiesUtil.get("LBE_LOGIN_USERID");//webservice用户:oacowork
//    public static final String LBE_LOGIN_PASSWORD = SysPropertiesUtil.get("LBE_LOGIN_PASSWORD");//webservice用户
    public static final String LBE_LOGIN_USERID = "ws_user";//webservice用户：在livebos管理控制台，系统用户管理中添加webservice类型用户。
    public static final String LBE_LOGIN_PASSWORD = "shanda";//webservice用户

    static String SessionId = StringUtil.EMPTY;//全局使用
    static LBEBusinessService lbeBusinessService;
    static LBDocumentService lbDocumentService;

    static {
        LBEBusinessWebService lbeBusinessWebService = new LBEBusinessWebService();//基本对象
        lbeBusinessService = lbeBusinessWebService.getLBEBusinessServiceImplPort();

        LBDocumentWebService lbDocumentWebService = new LBDocumentWebService();//文档对象
        lbDocumentService = lbDocumentWebService.getLBDocumentServiceImplPort();
    }

    /**
     * 登录（账号自己提前建立好）
     * @return 返回登录后的sessionId。以后所有接口调用都要用到。
     */
    public static final String getLoginSessionId(){
        if(StringUtil.isBlank(LBE_SERVER_URL)){
            LOG.error("webservice address must be added as LBE_SERVER_URL in sys properties db. Webservice服务器地址没有在数据库的系统变量字典中添加【LBE_SERVER_URL】");
            throw new RuntimeException("Webservice服务器地址没有在数据库的系统变量字典中添加【LBE_SERVER_URL】");
        }
        LoginResult loginResult = lbeBusinessService.login(LBE_LOGIN_USERID, LBE_LOGIN_PASSWORD, "", "plain", "");//这个账户要提前在livebos中建立，允许调用WebService.
        String sessionId = loginResult.getSessionId();
        LOG.info(loginResult.getMessage() + sessionId);
        return sessionId;
    }

    /**
     * 下载附件文件
     * @param objectName livebos附件对象名
     * @param columnName 附件字段
     * @param attachRecordId 附件表的对应存储记录的id
     * @param itemId 附件字段中的单个附件编号
     * @return 文件流
     * @throws IOException
     */
    public static final Document getDocumentFile(String objectName, String columnName, String attachRecordId, String itemId) {

//        DocumentResult documentResult = lbDocumentService.getDocument(SessionId, "V_OA_SendDocument_NJCI_V3", "GDFJ", "937", "2");
        DocumentResult documentResult = lbDocumentService.getDocument(SessionId, objectName, columnName, attachRecordId, itemId);
        LOG.info("webservice调用远程方法执行："+documentResult.getMessage() + documentResult.getResult());
        if(documentResult.getResult()==-2){
            //执行失败，会话过期，重新获取。
            synchronized (SessionId){
                SessionId = getLoginSessionId();
            }
            documentResult = lbDocumentService.getDocument(SessionId, objectName, columnName, attachRecordId, itemId);
        }else if(documentResult.getResult()==-1){
            throw new RuntimeException(documentResult.getMessage());
        }
        Document document = documentResult.getDocument();
        //以下为文件操作示例
//        InputStream inputStream = null;
//        if(document!=null){
//            String fileName = document.getFilename();
//            long length = document.getLength();
//            DataHandler dataHandler = document.getDocumentData();
//            String contentType = dataHandler.getContentType();
//            inputStream = dataHandler.getInputStream();
//            LOG.info("移动端通过WebService下载文件名："+fileName);
//            LOG.info("类型："+contentType);
//            LOG.info("长度："+length);
//        }
        return document;
    }

    /**
     * 查询发文所关联的所有附件基本信息
     * @param objectName livebos附件对象名
     * @param columnName 附件字段
     * @param attachRecordId 附件表的对应存储记录的id
     * @return
     * @throws IOException
     */
    public static final List<DocumentEntry> queryDocumentEntry(String objectName, String columnName, String attachRecordId) {

        DocumentEntryResult documentEntryResult = lbDocumentService.queryEntry(SessionId, objectName, columnName, attachRecordId);
        LOG.info("webservice调用远程方法执行："+documentEntryResult.getMessage() + documentEntryResult.getResult());
        if(documentEntryResult.getResult()==-1){
            throw new RuntimeException(documentEntryResult.getMessage());

        }else if(documentEntryResult.getResult()==-2){
            //执行失败，会话过期，重新获取。
            synchronized (SessionId){
                SessionId = getLoginSessionId();
            }
            documentEntryResult = lbDocumentService.queryEntry(SessionId, objectName, columnName, attachRecordId);
        }
        List<DocumentEntry> documentEntries = documentEntryResult.getEntrys();
        return documentEntries;
    }

    /**
     * 查询指定人发起和参与的全部流程
     * @return
     * @throws IOException
     */
    public static final List<WorkflowProfile> queryWorkflowDescribeByOwner(String uid) {

        String sessionId = getLoginSessionId();
        WorkflowDescribeResponse workflowDescribeResponse = lbeBusinessService.queryWorkflowDescribe(sessionId, uid, false);
        List<WorkflowProfile> workflowProfiles = workflowDescribeResponse.getWorkflowDescribes();

        return workflowProfiles;
    }

    /**
     * 查询指定人的通知/待办数量
     * @return
     * @throws IOException
     */
    public static final NoticeResult queryNoticeByCaller(String uid) {

        String sessionId = getLoginSessionId();
        NoticeResult result = lbeBusinessService.getNotice(sessionId, uid, 0);
        LOG.info("webservice调用远程方法执行："+result.getMessage() + result.getResult());
        if(result.getResult()==-2){
            //执行失败，会话过期，重新获取。
            synchronized (SessionId){
                SessionId = getLoginSessionId();
            }
            result = lbeBusinessService.getNotice(sessionId, uid, 0);
        }else if(result.getResult()==-1){
            throw new RuntimeException(result.getMessage());
        }

        return result;
    }

    /**
     * 查询流程跟踪。即制定流程的历史步骤信息
     * @param objectName livebos对象名
     * @return
     * @throws IOException
     */
    public static final List<LbRecord> query(String objectName) {

        String sessionId = getLoginSessionId();

        QueryOption option = new QueryOption();
        option.setBatchNo(1);
        option.setBatchSize(5);
        option.setOrderBy("id");
        QueryResult queryResult = lbeBusinessService.query(sessionId, objectName, null, null, option);
        LOG.info("webservice调用远程方法执行："+queryResult.getMessage() +"。状态："+ queryResult.getResult());
        if(queryResult.getResult()==-2){
            //执行失败，会话过期，重新获取。
            synchronized (SessionId){
                SessionId = getLoginSessionId();
            }
            queryResult = lbeBusinessService.query(sessionId, objectName, null, null, option);
        }else if(queryResult.getResult()==-1){
            throw new RuntimeException(queryResult.getMessage());
        }
        List<LbRecord> lbRecords = queryResult.getRecords();
        LOG.info("query>>>==" + queryResult.getCount());
        for(ColInfo colInfo:queryResult.getMetaData().getColInfo()){
            LOG.info("query>>>==" + colInfo.getName());
            LOG.info("query>>>==" + colInfo.getLabel());
            LOG.info("------");
        }
        return lbRecords;
    }

    /**
     * 查询流程跟踪。即制定流程的历史步骤信息
     * @param uid livebos流程执行人id
     * @return
     * @throws IOException
     */
    public static final List<LbRecord> queryTasks(String uid) {

        String sessionId = getLoginSessionId();

        QueryOption option = new QueryOption();
        QueryResult queryResult = lbeBusinessService.queryTasks(sessionId, uid, option);
        LOG.info("webservice调用远程方法执行："+queryResult.getMessage() + queryResult.getResult());
        if(queryResult.getResult()==-2){
            //执行失败，会话过期，重新获取。
            synchronized (SessionId){
                SessionId = getLoginSessionId();
            }
            queryResult = lbeBusinessService.queryTasks(sessionId, uid, option);
        }else if(queryResult.getResult()==-1){
            throw new RuntimeException(queryResult.getMessage());
        }
        List<LbRecord> lbRecords = queryResult.getRecords();
        LOG.info("queryTasks>>>==" + queryResult.getCount());
        for(ColInfo colInfo:queryResult.getMetaData().getColInfo()){
            LOG.info("queryTasks>>>==" + colInfo.getName());
            LOG.info("queryTasks>>>==" + colInfo.getLabel());
            LOG.info("------");
        }
        return lbRecords;
    }

    /**
     * 查询流程跟踪。即制定流程的历史步骤信息
     * @param instanceId livebos流程id
     * @return
     * @throws IOException
     */
    public static final List<LbRecord> queryWorkStepDetail(long instanceId) {

        String sessionId = getLoginSessionId();

        QueryOption option = new QueryOption();
//        lbeBusinessService.queryTasks(sessionId, uid, option);
//        NoticeResult noticeResult = lbeBusinessService.getNotice(sessionId, uid, 0);
        QueryResult queryResult = lbeBusinessService.queryWorkStepDetail(sessionId, instanceId, option);
        LOG.info("webservice调用远程方法执行："+queryResult.getMessage() + queryResult.getResult());
        if(queryResult.getResult()==-2){
            //执行失败，会话过期，重新获取。
            synchronized (SessionId){
                SessionId = getLoginSessionId();
            }
            queryResult = lbeBusinessService.queryWorkStepDetail(sessionId, instanceId, option);
        }else if(queryResult.getResult()==-1){
            throw new RuntimeException(queryResult.getMessage());
        }
        List<LbRecord> lbRecords = queryResult.getRecords();
        LOG.info("queryWorkStepDetail>>>==" + queryResult.getCount());
        for(ColInfo colInfo:queryResult.getMetaData().getColInfo()){
            LOG.info("queryWorkStepDetail>>>col==" + colInfo.getName());
            LOG.info("queryWorkStepDetail>>>col==" + colInfo.getLabel());
            LOG.info("------");
        }
        return lbRecords;
    }

}
